package com.logistica.metropolitana.services;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.logistica.metropolitana.converters.UsuariosConverter;
import com.logistica.metropolitana.db.daos.UsuarioDAO;
import com.logistica.metropolitana.db.model.Grupo;
import com.logistica.metropolitana.db.model.GrupoPermiso;
import com.logistica.metropolitana.db.model.Permiso;
import com.logistica.metropolitana.db.model.Usuario;
import com.logistica.metropolitana.exceptions.UsuarioException;
import com.logistica.metropolitana.web.views.PermisoView;
import com.logistica.metropolitana.web.views.UsuarioView;

@Service
public class UsuarioService {

	private final Logger logger = LoggerFactory.getLogger(UsuarioService.class);
	
	@Autowired
	UsuarioDAO usuarioDAO;
	
	public Map<String, List<PermisoView>> getRolesPermisos() throws UsuarioException {
		
		Map<String, List<PermisoView>> rolPermisosMap = Maps.newLinkedHashMap();
		try{
			List<Grupo> rolesList = usuarioDAO.getListaDeRoles();			
			for(Grupo grupo : rolesList){
				List<PermisoView> permisoList = Lists.newArrayList();				
				for(GrupoPermiso gPermiso : grupo.getGrupoPermisos()){
					logger.info("Nombre Grupo Permiso {}", gPermiso.getNombreGrupoPermiso());
					
					permisoList.add(new PermisoView(gPermiso.getIdGrpp().intValue(),
							gPermiso.getNombreGrupoPermiso()));
				}				
				rolPermisosMap.put(grupo.getNombreGrupo(), permisoList);
			}
		}catch(UsuarioException uException){
			throw uException;
		}catch(Exception e){
			UsuarioException fException = new UsuarioException(e, 
					UsuarioException.LAYER_SERVICE, UsuarioException.ACTION_SELECT);
			throw fException;
		}
		return rolPermisosMap;
	}
	
	public List<UsuarioView> getUsuarios() throws UsuarioException {
		List<UsuarioView> usuarioList = Lists.newArrayList();
		try{
			UsuariosConverter converter = new UsuariosConverter();			
			for(Usuario usuario : usuarioDAO.getListaDeUsuarios()){
				usuarioList.add(converter.convertEntityToView(usuario));
			}			
		}catch(UsuarioException uException){
			throw uException;
		}catch(Exception e){
			UsuarioException fException = new UsuarioException(e, 
					UsuarioException.LAYER_SERVICE, UsuarioException.ACTION_SELECT);
			throw fException;
		}
		return usuarioList;
	}
	
	public Map<String, List<PermisoView>> getUsuarioPermisos(String username) throws UsuarioException {
		Map<String, List<PermisoView>> usuarioPermisosMap = Maps.newLinkedHashMap();
		try{			
			List<String> permisos = usuarioDAO.getPermisosByUsername(username);			
			List<Grupo> grupoList = usuarioDAO.getListaDeRoles();			
			for(Grupo grupo : grupoList){
				List<PermisoView> permisoList = Lists.newArrayList();				
				for(GrupoPermiso gPermiso :grupo.getGrupoPermisos()){
					
					String nombrePermiso = gPermiso.getCodigoGrupoPermiso();					
					boolean hasPermiso = hasPermiso(permisos, nombrePermiso);
					permisoList.add(new PermisoView(gPermiso.getIdGrpp()
							.intValue(), nombrePermiso, hasPermiso));
				}				
				usuarioPermisosMap.put(grupo.getNombreGrupo(), permisoList);
			}
		}catch(UsuarioException uException){
			throw uException;
		}catch(Exception e){
			UsuarioException fException = new UsuarioException(e, 
					UsuarioException.LAYER_SERVICE, UsuarioException.ACTION_SELECT);
			throw fException;
		}
		return usuarioPermisosMap;
	}
	
	private boolean hasPermiso(List<String> permisosDelUsuario, String nombrePermiso){
		boolean hasPermiso = false;
		if(permisosDelUsuario != null){
			if(!permisosDelUsuario.isEmpty()){
				for(String permiso : permisosDelUsuario){
					if(nombrePermiso.equals(permiso)){
						hasPermiso = true;
						break;
					}
				}
			}
		}
		return hasPermiso;
	}
	
	public UsuarioView getUsuarioByUsername(String username) throws UsuarioException {
		UsuarioView usuarioView = new UsuarioView();
		try{
			UsuariosConverter converter = new UsuariosConverter();
			usuarioView = converter.convertEntityToView(
					usuarioDAO.getUsuarioByUsername(username));
		}catch(UsuarioException uException){
			throw uException;
		}catch(Exception e){
			UsuarioException fException = new UsuarioException(e, 
					UsuarioException.LAYER_SERVICE, UsuarioException.ACTION_SELECT);
			throw fException;
		}
		return usuarioView;
	}
	
	
	public void addPermisos(UsuarioView view) throws UsuarioException {
		try{

			List<Permiso> permisos = Lists.newArrayList();

			for(PermisoView pv : view.getPermisos()){
				if(pv.isSelected()){
					Permiso permiso = new Permiso();
					permiso.setFechaAltaPermiso(new Timestamp(System.currentTimeMillis()));
					permiso.setIdPerm(new Long(pv.getPermisoId()));
					permiso.setNombrePermiso(pv.getNombrePermiso());
					permisos.add(permiso);
				}
			}
			
			usuarioDAO.addPermisosPorUsuario(permisos, view.getUserId());
			
		}catch(UsuarioException uException){
			throw uException;
		}catch(Exception e){
			UsuarioException fException = new UsuarioException(e, 
					UsuarioException.LAYER_SERVICE, UsuarioException.ACTION_INSERT);
			throw fException;
		}
	}
}
